#ifndef _IRENDERABLE_H_
#define _IRENDERABLE_H_

#include "../src/Util/Vector.h"
#include "../src/Util/Matrix.h"
#include "RenderComponents.h"

using namespace RenderComponent;

class IRenderable
{
protected:
	bool m_isVisible;
	unsigned m_shaderID;
	int m_meshID;
	int m_textureID;
	
	vec3 m_orientation;	// Orientation of the object in the world (angles)
	Color  m_color;

	Matrix4 m_local;
	Matrix4 m_texture;

public:
	IRenderable() : m_shaderID(0), m_meshID(-1), m_textureID(-1), m_isVisible(true) { }
	~IRenderable() { }

	IRenderable(const IRenderable& rhs)
	{
		m_isVisible = rhs.m_isVisible;
		m_shaderID = rhs.m_shaderID;
		m_meshID = rhs.m_meshID;
		m_textureID = rhs.m_textureID;
		m_orientation = rhs.m_orientation;
		m_local = rhs.m_local;
		m_texture = rhs.m_texture;
		m_color = rhs.m_color;
	}

	IRenderable& operator=(const IRenderable& rhs)
	{
		if(this == &rhs) return *this;

		m_isVisible = rhs.m_isVisible;
		m_shaderID = rhs.m_shaderID;
		m_meshID = rhs.m_meshID;
		m_textureID = rhs.m_textureID;
		m_orientation = rhs.m_orientation;
		m_local = rhs.m_local;
		m_texture = rhs.m_texture;
		m_color = rhs.m_color;

		return *this;
	}

	void SetShaderID(unsigned shaderID) { m_shaderID = shaderID; }
	void SetMeshID(int meshID) { m_meshID = meshID; }
	void SetTextureID(int textureID) { m_textureID = textureID; }
	void SetColor(Color color) { m_color = color; }
	void SetVisible(bool isVisible) { m_isVisible = isVisible; }
	void SetLocalMatrix(Matrix4& mat) { m_local = mat; }
	void SetTextureMatrix(Matrix4& mat) { m_texture = mat; }
	void SetOrientation(const vec3& orient) { m_orientation = orient; }
	void SetOrientation(float x = 0.0f, float y = 0.0f, float z = 0.0f) { m_orientation = vec3(x, y, z); }
	
	Color GetColor() const { return m_color; }
	int GetMeshID() const { return m_meshID; }
	int GetTextureID() const { return m_textureID; }
	unsigned GetShaderID() const { return m_shaderID; }
	bool IsVisible() const { return m_isVisible; }
	Matrix4& GetLocalMatrix() { return m_local; }
	Matrix4 GetLocalMatrix() const { return m_local; }
	Matrix4& GetTextureMatrix() { return m_texture; }
	Matrix4 GetTextureMatrix() const { return m_texture; }
	vec3& GetOrientation() { return m_orientation; }
	vec3 GetOrientation() const { return m_orientation; }
};

inline bool operator>(const IRenderable& A, const IRenderable& B)
{
	return (A.GetLocalMatrix().wAxis().Z() > B.GetLocalMatrix().wAxis().Z());
}

inline bool operator<(const IRenderable& A, const IRenderable& B)
{
	return (A.GetLocalMatrix().wAxis().Z() < B.GetLocalMatrix().wAxis().Z());
}

#endif